#include<bits/stdc++.h>
using namespace std;
const int N = (3e5+10)*30;
char buf[1 << 20], *p1 = buf, *p2 = buf, obuf[1 << 20], *O = obuf;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? EOF : *p1++)
#define putchar(x) \
    ((O - obuf < (1 << 20)) ? (*O++ = x) : (fwrite(obuf, O - obuf, 1, stdout), O = obuf, *O++ = x))
template <class T>
void read(T &x) {
    int f = 1;
    x = 0;
    char ch = getchar();
    for (; 48 > ch || ch > 57; ch = getchar())
        if (ch == '-')
            f = 0;
    for (; 48 <= ch && ch <= 57; ch = getchar()) x = (x << 3) + (x << 1) + ch - 48;
    x = f ? x : -x;
}
void write(int x, char ch = '\n') {
    if (x < 0)
        putchar('-'), x = -x;
    if (!x)
        return (void)(putchar(48), putchar(ch));
    static int stk[30], tp;
    tp = 0;
    while (x) stk[++tp] = x % 10, x /= 10;
    while (tp) putchar(stk[tp--] + 48);
    putchar(ch);
}
int son[N][2];
int siz[N];
int val[N];
int pcnt;
inline int gen(){
    int now = ++pcnt;
    son[now][0] =son[now][1]= val[now] = siz[now]= 0;
    return now;
}
inline int gen(int v)
{
    int now = gen();
    val[now] = v;
    siz[now] = 1;
    return now;
}
inline void push_up(int now){
    siz[now] = siz[son[now][0]] + siz[son[now][1]];
}
inline int gen(int x,int y){
    int now = gen();
    son[now][0] = x;
    son[now][1] = y;
    push_up(now);
    return now;
}
#define ls(x) son[x][0]
#define rs(x) son[x][1]
inline void balence(int &x){
    bool r = siz[son[x][1]] > siz[son[x][0]];
    if(siz[son[x][r]] < 3*siz[son[x][!r]]){
        return;
    }
    if(siz[son[son[x][r]][!r]] > 2*siz[son[son[x][r]][r]]){
        if(r){
            x = gen(gen(ls(x),ls(ls(rs(x)))),gen(rs(ls(rs(x))),rs(rs(x))));
        }else{
            x = gen(gen(ls(ls(x)),ls(rs(ls(x)))),gen(rs(rs(ls(x))),rs(x)));
        }
        return;
    }else{
        if(r){
            x = gen(gen(ls(x),ls(rs(x))),rs(rs(x)));
        }else{
            x = gen(ls(ls(x)),gen(rs(ls(x)),rs(x)));
        }
        return;
    }
}
void copy(int &x){
    int now = gen();
    son[now][0] = son[x][0];
    son[now][1] = son[x][1];
    siz[now] = siz[x];
    val[now] = val[x];
    x = now;
}
void insert(int &x,int rnk,int v){
    if(!x){
        x = gen(v);
        return;
    }
    if(!son[x][0]){
        if(rnk == 1){
            x = gen(gen(v),x);
        }else{
            x = gen(x,gen(v));
        }
        return;
    }
    copy(x);
    if(siz[ls(x)] >= rnk){
        insert(ls(x),rnk,v);
    }else{
        insert(rs(x),rnk - siz[ls(x)],v);
    }
    push_up(x);
    balence(x);
}
void remove(int &x,int rnk){
    if(!son[x][0]){
        if(rnk == 1){
            x = 0;
        }
        return;
    }
    copy(x);
    if(siz[ls(x)] >= rnk){
        remove(ls(x),rnk);
        if(!ls(x)){
            x = rs(x);
            return;
        }
    }else{
        remove(rs(x),rnk - siz[ls(x)]);
        if(!rs(x)){
            x = ls(x);
            return;
        }
    }
    push_up(x);
    balence(x);
}
int nth(int x,int rnk){
    if(!son[x][0]){
        return val[x];
    }
    if(siz[ls(x)] >= rnk){
        return nth(ls(x),rnk);
    }else{
        return nth(rs(x),rnk - siz[ls(x)]);
    }
}
int rc;
int roots[N];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    read(n);
    for(int i = 1;i<=n;i++){
        int opt,t;
        read(opt);
        read(t);
        if(opt == 1){
            roots[++rc] = roots[t];
            int k,x;
            read(k);
            read(x);
            insert(roots[rc],k,x);
        }else if(opt == 2){
            roots[++rc] = roots[t];
            int k;
            read(k);
            remove(roots[rc],k);
        }else{
            int k;
            read(k);
            write(nth(roots[t],k));
        }
    }

    fwrite(obuf, O - obuf, 1, stdout);
}